package com.kaishu.misp.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.kaishu.misp.dao.HibernateDao;

@Repository
public class HibernateDaoImpl<T> implements HibernateDao<T>{

	@Autowired
	private SessionFactory sessionFactory;

	/**
	 * 获得当前事物的session
	 * 
	 * @return org.hibernate.Session
	 */
	public Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}
	/**
	 * 添加
	 * @param entity
	 * @return
	 */
	@Override
	public void save(T entity) {
		getCurrentSession().save(entity);
	}
	/**
	 * 修改
	 * @param entity
	 */
	@Override
	public void update(T entity) {
		if (entity != null) {
			getCurrentSession().update(entity);
		}
	}
	
	/**
	 * 删除
	 * @param entity
	 */
	@Override
	public void delete(T entity) {
		if (entity != null) {
			getCurrentSession().delete(entity);
		}
	}
	
	/**
	 * 通过id删除
	 * @param entity
	 */
	@Override
	public void deleteById(Serializable id) {
		delete(get(id));
	}
	
	/**
	 * 得到对象
	 * @param id
	 * @return
	 */
	@Override
	public T get(Serializable id) {
		return (T) getCurrentSession().get(getEntity(), id);
	}
	/**
	 * 查所有
	 * @return
	 */
	@Override
	public List<T> findAll() {
		Criteria criteria = getCurrentSession().createCriteria(getEntity());
		return criteria.list();
	}
	
	/**
	 * 分页查所有
	 * @param page
	 * @param rows
	 * @param sort
	 * @param order
	 * @return
	 */
	@Override
	public List<T> findAll(int page, int rows, String sort, String order) {
		Criteria criteria = getCurrentSession().createCriteria(getEntity());
		criteria.setFirstResult((page-1) * rows);
		criteria.setMaxResults(rows);
		if ("asc".equals(order)) {
			criteria.addOrder(Order.asc(sort));
		} else {
			criteria.addOrder(Order.desc(sort));
		}
		return criteria.list();
	}
	
	/**
	 * 统计总数
	 * @return
	 */
	@Override
	public int countAll() {
		Criteria criteria = getCurrentSession().createCriteria(getEntity());
		return criteria.list().size();
	}
			
	/**
	 * 查询
	 * @param hql
	 * @return
	 */
	@Override
	public T get(String hql) {
		Query q = getCurrentSession().createQuery(hql);
		List<T> l = q.list();
		if (l != null && l.size() > 0) {
			return l.get(0);
		}
		return null;
	}

	/**
	 * 查询
	 * @param hql
	 * @param propertys
	 * @return
	 */
	@Override
	public T get(String hql, Map<String, Object> propertys) {
		Query q = getCurrentSession().createQuery(hql);
		if (propertys != null && !propertys.isEmpty()) {
			for (String key : propertys.keySet()) {
				q.setParameter(key, propertys.get(key));
			}
		}
		List<T> l = q.list();
		if (l != null && l.size() > 0) {
			return l.get(0);
		}
		return null;
	}

	/**
	 * 查询
	 * @param hql
	 * @return
	 */
	@Override
	public List<T> find(String hql) {
		Query q = getCurrentSession().createQuery(hql);
		return q.list();
	}

	/**
	 * 查询
	 * @param hql
	 * @param params
	 * @return
	 */
	@Override
	public List<T> find(String hql, Map<String, Object> params) {
		Query q = getCurrentSession().createQuery(hql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				q.setParameter(key, params.get(key));
			}
		}
		return q.list();
	}
	
	@Override
	public List<T> findByProperty(String propertyName, Object value) {
		Criterion criterion = Restrictions.eq(propertyName, value);
		return createCriteria(criterion).list();
	}

	@Override
	public boolean isExist(String propertyName, Object value) {
		boolean flag = false;
		if (findByProperty(propertyName, value).size()>0){
			flag = true;
		}
		return flag;
	}
	
	@Override
	public Criteria createCriteria(Criterion... criterions) {
		Criteria criteria = createCriteria();
		for (Criterion c : criterions) {
			criteria.add(c);
		}
		return criteria;
	}
		
	/**
	 * 得到泛型类
	 * @return Class
	 */
	protected Class<T> getEntity(){
		Class<T> entityClass = (Class<T>)((ParameterizedType)getClass().getGenericSuperclass()).getActualTypeArguments()[0];
		return entityClass;
	}
	
}
